package com.eblacorp.archive.util.ce;

import java.io.IOException;
import java.io.Serializable;
import java.net.URLEncoder;
import java.security.Principal;

import javax.security.auth.Subject;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;

import com.eblacorp.archive.util.HttpUtil;
import com.filenet.api.util.Id;
import com.filenet.api.util.UserContext;
import com.filenet.api.core.*;
import com.filenet.wcm.toolkit.server.util.prefs.WcmConfiguration;
import com.filenet.wcm.toolkit.util.WcmEncodingUtil;

public class CeConnectionUtil implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 3220000256711742302L;
	final static Log log = LogFactory.getLog(CeConnectionUtil.class);
	
	
	private String userName;
	private String uri;
	private String password;
	private String stanza;
	private String objectStoreName;
	
	private Connection connection;
	private Domain domain;
	private Subject subject;
	private ObjectStore objectStore;
	private String bootStrapPropertiesPath;
	private String setCredentialsUrl;
	private String webClient;
	private String webClientProtocol;
	private String webClientServerName;
	private String webClientPort;
	private String wcmJavaViewerUrl;
	private String userToken;
	private StringBuffer userTokenRequestParams;
	private long userTokenLastCreationTime;
	
	
	public void init(){
		UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		System.out.println(userDetails.getPassword());
		System.out.println(userDetails.getUsername());
		userName = SecurityContextHolder.getContext().getAuthentication().getName();
		password =  "p8admin2014";
		userToken = null;
		userTokenLastCreationTime = 0;
		try {
			connection = Factory.Connection.getConnection(uri);
			WcmConfiguration.loadBootstrap(bootStrapPropertiesPath);
			subject = UserContext.createSubject(connection,userName,password,stanza);
			pushUserSubject();
			domain = Factory.Domain.fetchInstance(connection, null, null);
			objectStore = Factory.ObjectStore.fetchInstance(domain, objectStoreName, null);
			popUserSubject();
			
			setCredentialsUrl = webClientProtocol + "://" + webClientServerName + ":" + webClientPort + "/" + webClient + "/setCredentials";
			wcmJavaViewerUrl = webClientProtocol + "://" + webClientServerName + ":" + webClientPort + "/" + webClient + "/getContent?objectStoreName=" + objectStore.get_Name() + "&vsId=DocID&id=DocID&objectType=document&ut=";
			
			userTokenRequestParams = new StringBuffer();
			userTokenRequestParams.append("op").append("=").append("getUserToken").append("&")
			.append("userId").append("=").append(WcmEncodingUtil.encodeLabel(userName)).append("&")
			.append("password").append("=").append(WcmEncodingUtil.encodeLabel(password)).append("&")
			.append("verify").append("=").append("true");
		} catch (Exception e) {
			log.error(e);
		}
	}
	
	public void pushUserSubject(){
		UserContext.get().pushSubject(subject);
		
	}
	
	public long getTokenTimeoutInterval(){
		long tokenTimeoutInterval = 0;
		try {
			WcmConfiguration.reloadBootstrap();
			tokenTimeoutInterval = (long)WcmConfiguration.getBootstrapPrefs().getTokenTimeoutInterval();
			tokenTimeoutInterval *= (60L*1000L);
		} catch (IOException e) {
			log.error(e);
		}
		return tokenTimeoutInterval;
	}
	
	public String getWcmJavaViewerUrl(Id id){
		long tokenTimeoutInterval = 0;
		try{
			tokenTimeoutInterval = getTokenTimeoutInterval();
			if(userToken == null || (userTokenLastCreationTime + tokenTimeoutInterval)  <= System.currentTimeMillis()){
				userToken = HttpUtil.sendHttpRequest(userTokenRequestParams.toString(), setCredentialsUrl);
				userToken = URLEncoder.encode(userToken, "UTF-8");
				userTokenLastCreationTime = System.currentTimeMillis();
			}
			if(id != null){
				wcmJavaViewerUrl = wcmJavaViewerUrl.replace("DocID", id.toString());
			}
		}catch(Exception e){
			log.error(e);
		}
		return wcmJavaViewerUrl + userToken;
	}
	
	public void popUserSubject(){
		UserContext.get().popSubject();
	}
	
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getUri() {
		return uri;
	}
	public void setUri(String uri) {
		this.uri = uri;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getStanza() {
		return stanza;
	}
	public void setStanza(String stanza) {
		this.stanza = stanza;
	}
	public String getObjectStoreName() {
		return objectStoreName;
	}
	public void setObjectStoreName(String objectStoreName) {
		this.objectStoreName = objectStoreName;
	}


	public ObjectStore getObjectStore() {
		return objectStore;
	}

	public String getBootStrapPropertiesPath() {
		return bootStrapPropertiesPath;
	}

	public void setBootStrapPropertiesPath(String bootStrapPropertiesPath) {
		this.bootStrapPropertiesPath = bootStrapPropertiesPath;
	}

	public String getWebClient() {
		return webClient;
	}

	public void setWebClient(String webClient) {
		this.webClient = webClient;
	}

	public String getWebClientProtocol() {
		return webClientProtocol;
	}

	public void setWebClientProtocol(String webClientProtocol) {
		this.webClientProtocol = webClientProtocol;
	}

	public String getWebClientServerName() {
		return webClientServerName;
	}

	public void setWebClientServerName(String webClientServerName) {
		this.webClientServerName = webClientServerName;
	}

	public String getWebClientPort() {
		return webClientPort;
	}

	public void setWebClientPort(String webClientPort) {
		this.webClientPort = webClientPort;
	}
}
